﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using InvestmentIntelligence.DbModel.Models;

namespace InvestmentIntelligence.Data.Repository.EFImplementation
{
    public class FundBookRepository : IIPRepository<FundBookEntity>, IFundBookUpdatableRepository
    {
        public int AddFund(FundBookEntity fund)
        {
            Add(fund);
            return fund.Id;
        }

        public void AddFunds(List<FundBookEntity> funds)
        {
            Add(funds);
        }

        public List<T> GetListFunds<T>(Func<IQueryable<FundBookEntity>, IEnumerable<T>> f)
        {
            return
                GetList(dc => f(dc.Include("Fund").Include("FundBooks").Include("AnalysisGroups")));
        }

        public List<T> GetListFundsWithBooks<T>(Func<IQueryable<FundBookEntity>, IEnumerable<T>> f)
        {
            return
                GetList(
                    dc =>
                        f(dc.Include("FundBooks")
                            .Include("AnalysisGroups")
                            .Where(x => x.ParentId == null || x.ParentId == 0)));
        }

        public FundBookEntity Get(int bookId)
        {
            return Get(v => v.Id == bookId);
        }

        public FundBookEntity Get(string bookId)
        {
            return Get(v => v.OriginalId == bookId);
        }

        

        public FundBookEntity GetFundWithFundBooks(int fundId)
        {
            return Get(
                dc => dc.Include("FundBooks").Include("AnalysisGroups")
                .Single(x => x.Id == fundId));
        }

        public void AddFundBookToAnalysisGroup(int groupiId, int fundId)
        {
            RunUnitOfWork(data =>
                               {
                                   var fund = data.FundBookEntities.Include("AnalysisGroups").Single(x => x.Id == fundId);
                                   var group = data.AnalysisGroups.Single(x => x.Id == groupiId);
                                   fund.AnalysisGroups.Add(group);
                                   data.SaveChanges();
                                   return default(FundBookEntity);
                               });
        }

        public void RemoveFundBookFromAnalysisGroup(int groupiId, int fundId)
        {
            RunUnitOfWork(data =>
                               {
                                   var group = data.AnalysisGroups.Include("FundBookEntities").Single(x => x.Id == groupiId);
                                   var fund = data.FundBookEntities.Single(x => x.Id == fundId);
                                   group.FundBookEntities.Remove(fund);
                                   data.SaveChanges(); return default(FundBookEntity);
                               });
        }

        public void UpdateByOriginalId(FundBookEntity book)
        {
            RunUnitOfWork(data =>
            {
                var savedBook = data.FundBookEntities.Single(x => x.OriginalId.Equals(book.OriginalId, StringComparison.InvariantCultureIgnoreCase));
                savedBook.ParentId = book.ParentId;
                savedBook.Name = book.Name;
                savedBook.CurrencyId = book.CurrencyId;
                data.SaveChanges(); return default(FundBookEntity);
            });
        }

        public List<T> GetAllActiveIds<T>(Func<IQueryable<int>, IEnumerable<T>> f)
        {
            return GetList(dc => f(dc.Where(fb => fb.IsActive && fb.HasOpenPosition).Select(fb => fb.Id)));
        }

        public void UpdateHasOpenPosition(int id)
        {
            const string sql = @"
UPDATE
fund
SET
fund.HasOpenPosition = (SELECT CASE WHEN (SELECT SUM(Quantity) FROM [TradingData].[Trade] WHERE FundBookEntityId=fund.Id) = 0 THEN 0 ELSE 1 END)
FROM
[TradingData].[FundBookEntity] fund
WHERE
Id=@FundBookEntityId"
            ;
            ExecuteSqlCommand(sql, new SqlParameter("@FundBookEntityId", id));
        }
    }
}